/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.approvalformat.core.util;

import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.variable.CommonVariableCollection;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.web.approvalformat.api.entity.schema.Entity;
import com.inspur.edp.web.approvalformat.api.entity.schema.Field;
import com.inspur.edp.web.approvalformat.api.entity.schema.FormSchema;
import com.inspur.edp.web.approvalformat.api.entity.schema.type.EntityType;
import com.inspur.edp.web.common.customexception.WebCustomException;
import com.inspur.edp.web.common.utility.StringUtility;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 审批单据schema工具类
 *
 * @author Xu‘fa Wang
 * @date 2020/6/8 16:23
 */
public class ApprovalFormSchemaUtil {
    public ApprovalFormSchemaUtil() {
    }

    /**
     * 基于ViewModel构建表单Schema
     *
     * @param vm
     * @return
     */
    public static FormSchema constructSchema(GspViewModel vm) {
        FormSchema schema = new FormSchema() {
            {
                this.setId(vm.getId());
                this.setCode(vm.getCode());
                this.setName(vm.getName());
                this.setSourceType("vo");
                this.setEntities(Collections.singletonList(constructEntity(vm.getMainObject())));
                this.setVariables(constructFields(vm.getVariables().getContainElements()));
                //此时不需初始化eapiId
            }
        };
        return schema;
    }

    private static List<Field> constructFields(CommonVariableCollection variables) {
        List<Field> variableList = new ArrayList<>();
        if (variables == null || variables.size() <= 0) {
            return variableList;
        }
        variables.forEach(field -> {
            TypeBuildingContext context = TypeBuildingContext.createTypeBuildingContext(field, null);
            Field variable = FieldUtil.constructField(context, null);
            variableList.add(variable);
        });
        return variableList;
    }

    private static Entity constructEntity(GspViewObject mainObject) {
        Entity entity = new Entity() {
            {
                this.setId(mainObject.getId());
                this.setCode(mainObject.getCode());
                this.setName(mainObject.getName());
                this.setLabel(StringUtility.toCamelCase(mainObject.getCode()) + "s");
                this.setType(constructEntityType(mainObject));
            }
        };
        return entity;
    }

    private static EntityType constructEntityType(GspViewObject mainObject) {
        if (mainObject.getIDElement() == null) {
            Object[] params = {mainObject.getID(), mainObject.getName()};
            throw new WebCustomException(ApprovalFormatTranslateUtil.getMessage("VOIDElementNull", params));
        }
        List<Field> fields = new ArrayList<>();
        for (IGspCommonField element : mainObject.getContainElements()) {
            fields.add(FieldUtil.createField(element, null));
        }
        List<Entity> entities = new ArrayList<>();
        for (IGspCommonObject childObject : mainObject.getContainChildObjects()) {
            entities.add(constructEntity((GspViewObject) childObject));
        }
        EntityType entityType = new EntityType(mainObject.getCode(), mainObject.getName(),
                StringUtility.toCamelCase(mainObject.getIDElement().getLabelID()), fields, entities);
        return entityType;
    }
}
